package cn.wolfcode.car.business.service.impl;

import cn.wolfcode.car.business.domain.Appointment;
import cn.wolfcode.car.business.domain.Statement;
import cn.wolfcode.car.business.mapper.AppointmentMapper;
import cn.wolfcode.car.business.query.AppointmentQuery;
import cn.wolfcode.car.business.service.IAppointmentService;
import cn.wolfcode.car.business.service.IStatementService;
import cn.wolfcode.car.common.base.page.TablePage;
import cn.wolfcode.car.common.base.page.TablePageInfo;
import cn.wolfcode.car.common.exception.BusinessException;
import cn.wolfcode.car.common.util.Convert;
import cn.wolfcode.car.common.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

@Service
@Transactional
public class AppointmentServiceImpl extends ServiceImpl<AppointmentMapper, Appointment> implements IAppointmentService {

    @Autowired
    private AppointmentMapper appointmentMapper;

    @Autowired
    private IStatementService statementService;

    @Override
    public TablePage<Appointment> query(AppointmentQuery qo) {
        Page<Appointment> page = new Page<>(qo.getPageNum(),qo.getPageSize());
        QueryWrapper<Appointment> wrapper = Wrappers.<Appointment>query();
        wrapper.eq("delete_flag",0);
        wrapper.like(StringUtils.isNotEmpty(qo.getCustomerName()),"customer_name",qo.getCustomerName());
        wrapper.like(StringUtils.isNotEmpty(qo.getCustomerPhone()),"customer_phone",qo.getCustomerPhone());
        wrapper.like(StringUtils.isNotEmpty(qo.getStatus()),"status",qo.getStatus());
        appointmentMapper.selectPage(page,wrapper);
        return new TablePage<Appointment>(page);
    }

    public void add(Appointment appointment) {
        /**
         * 1> 到店时间是客户到店之后点击到店按钮才添加的,新增的时候没有  可以在SQL语句中删除这个字段的新增
         * 2> 新增的时候状态默认设置为预约中
         */
        appointment.setCreateTime(new Date()); // 创建时间
        appointment.setStatus(Appointment.STATUS_APPOINTMENT); // 流程核心变量有默认值需要再次设置一遍,防止前端注入
        appointmentMapper.insert(appointment);
    }

    @Override
    public void update(Appointment appointment) {
        /**
         * 1> 编辑的时候只能是预约中才能编辑
         * 2> 编辑的时候到店时间,状态,创建时间不能修改,可以直接在SQL语句中删除对应字段的修改
         */
        // 安全性校验
        if (!Appointment.STATUS_APPOINTMENT.equals(appointment.getStatus())) {
            throw new BusinessException("只有预约中状态才能编辑");
        }
        UpdateWrapper<Appointment> wrapper = Wrappers.<Appointment>update();
        wrapper.set("customer_name",appointment.getCustomerName());
        wrapper.set("customer_phone",appointment.getCustomerPhone());
        wrapper.set("appointment_time",appointment.getAppointmentTime());
        wrapper.set("license_plate",appointment.getLicensePlate());
        wrapper.set("car_series",appointment.getCarSeries());
        wrapper.set("service_type",appointment.getServiceType());
        wrapper.set("info",appointment.getInfo());
        wrapper.eq("id",appointment.getId());
        wrapper.eq("delete_flag", Appointment.DELETE_NO);
        appointmentMapper.update(null,wrapper);
    }

    @Override
    public void deleteBatch(String ids) {
        Long[] dictIds = Convert.toLongArray(ids);
        for (Long dictId : dictIds) {
            // 安全性校验 只有预约中才能删除
            if (!Appointment.STATUS_APPOINTMENT.equals(this.getById(dictId).getStatus())) {
                throw new BusinessException("只有预约中才能删除");
            }
            UpdateWrapper<Appointment> wrapper = Wrappers.<Appointment>update();
            wrapper.set("delete_flag",Appointment.DELETE_YES);
            wrapper.eq("id",dictId);
            wrapper.eq("delete_flag", Appointment.DELETE_NO);
            appointmentMapper.update(null,wrapper);
        }
    }

    @Override
    public void cancel(Long id) {
        /**
         * 1> 当只有预约中的时候才能取消预约,其他时候都不能取消
         * 2> 取消预约只需要修改status为STATUS_CANCEL 即可
         */
        //安全性校验
        if (!Appointment.STATUS_APPOINTMENT.equals(this.getById(id).getStatus())) { // 如果不是预约中状态则不能取消
            throw new BusinessException("只有预约中状态才能取消");
        }
        UpdateWrapper<Appointment> wrapper = Wrappers.<Appointment>update();
        wrapper.set("status",Appointment.STATUS_CANCEL);
        wrapper.eq("id",id);
        wrapper.eq("delete_flag", Appointment.DELETE_NO);
        appointmentMapper.update(null,wrapper);
    }

    @Override
    public void arrival(Long id) {
        //安全性校验
        if (!Appointment.STATUS_APPOINTMENT.equals(this.getById(id).getStatus())) { // 如果不是预约中状态则不能到店
            throw new BusinessException("只有预约中状态才能到店操作");
        }
        // 到店除了到店时间之外,状态也要修改为已到店
        UpdateWrapper<Appointment> wrapper = Wrappers.<Appointment>update();
        wrapper.set("actual_arrival_time", new Date());
        wrapper.set("status",Appointment.STATUS_ARRIVAL);
        wrapper.eq("id",id);
        wrapper.eq("delete_flag", Appointment.DELETE_NO);
        appointmentMapper.update(null,wrapper);
    }

    @Override
    @Transactional
    public Statement generateStatement(Long appointmentId) {
        // 只有到店和已结算才能生成结算单或者查看结算单明细
        Appointment appointment = appointmentMapper.selectById(appointmentId);
        Integer status = appointment.getStatus();
        if (!(status == 1 || status == 4)) { // 如果不是到店或者已结算
            throw new BusinessException("只有到店或者已结算才能生成/查看结算单");
        }
        // 查询是否有生成过结算单
        Statement statement = statementService.selectByAppointmentId(appointmentId);
        // 当没有生成过结算单的时候,需要新增一个结算单
        if (statement == null) {
            statement = new Statement();
            statement.setCustomerName(appointment.getCustomerName());
            statement.setCustomerPhone(appointment.getCustomerPhone());
            statement.setActualArrivalTime(appointment.getActualArrivalTime());
            statement.setLicensePlate(appointment.getLicensePlate());
            statement.setCarSeries(appointment.getCarSeries());
            statement.setServiceType(appointment.getServiceType());
            statement.setAppointmentId(appointmentId);
            statement.setStatus(Statement.STATUS_CONSUME);
            statement.setInfo(appointment.getInfo());
            statementService.add(statement);
        }
        // 如果有生成,则直接返回结算单
        return statement;
    }

    @Override
    public void changeStatus(Long id, Integer status) {
        UpdateWrapper<Appointment> wrapper = Wrappers.<Appointment>update();
        wrapper.set("status",status);
        wrapper.eq("id",id);
        wrapper.eq("delete_flag", Appointment.DELETE_NO);
        appointmentMapper.update(null, wrapper);
    }
}
